package com.jzo2o.orders.manager.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.api.trade.enums.RefundStatusEnum;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersRefundMapper;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.service.IOrdersRefundService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 订单退款表 服务实现类
 * </p>
 * @author itcast
 * @since 2023-09-07
 */
@Service
public class OrdersRefundServiceImpl extends ServiceImpl<OrdersRefundMapper, OrdersRefund> implements IOrdersRefundService {
    @Resource
    private RefundRecordApi refundApi;
    @Resource
    private IOrdersCommonService ordersCommonService;
    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 查询指定数量的退款订单
     * @param count 数量
     */
    @Override
    @SuppressWarnings("unchecked")
    public List<OrdersRefund> queryRefundOrderListByCount(Integer count) {
        return lambdaQuery()
                .orderByAsc(OrdersRefund::getCreateTime)
                .last("limit " + count)
                .list();
    }

    @Override
    public boolean saveRefundInfo(OrderCancelDTO orderRefundInfo) {
        return SqlHelper.retBool(baseMapper.insert(OrdersRefund.builder()
                .id(orderRefundInfo.getId())
                .tradingOrderNo(orderRefundInfo.getTradingOrderNo())
                .realPayAmount(orderRefundInfo.getRealPayAmount())
                .build()));
    }

    @Override
    public void refundOrderByRefundRecord(OrdersRefund refundRecord) {
        ExecutionResultResDTO executionResultResDTO;
        try {
            executionResultResDTO = refundApi.refundTrading(refundRecord.getTradingOrderNo(), refundRecord.getRealPayAmount());
        } catch (Exception e) {
            log.error("执行退款接口出错, 出错信息如下", e);
            return;
        }

        Integer refundStatus = executionResultResDTO.getRefundStatus();
        if (ObjectUtils.isNotEmpty(executionResultResDTO) &&
                (RefundStatusEnum.SUCCESS.getCode().equals(refundStatus)
                        || RefundStatusEnum.FAIL.getCode().equals(refundStatus))) {
            // 退款成功/失败 1. 删除退款记录 2. 更新订单状态
            Long orderId = refundRecord.getId();
            transactionTemplate.executeWithoutResult(status -> {
                if (!SqlHelper.retBool(baseMapper.deleteById(orderId))) {
                    throw new DBException("删除退款记录失败");
                }

                if (!ordersCommonService.updateStatus(OrderUpdateStatusDTO.builder()
                        .id(orderId)
                        .targetStatus(OrderStatusEnum.CLOSED.getStatus())
                        .refundStatus(refundStatus)
                        .refundNo(executionResultResDTO.getRefundNo())
                        .refundId(executionResultResDTO.getRefundId())
                        .build())) {
                    throw new DBException("更新订单状态失败");
                }
            });
        }
    }
}